package Jets.loader
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	
	import Jets.events.JEvent;
	
	public class JResLoader extends EventDispatcher
	{
		static protected var _instance:JResLoader = null;
		
		private var ms_curLoadinfo:JLoadInfo = null;
		private var ms_loadingStatus:Boolean = false;
		private var ms_loadList:Dictionary;
		private var ms_loadKeys:Array;
		private var ms_loadSize:uint = 0;
		private var ms_loadLang:uint = 0;
		
		public function JResLoader(cls:privateClass) 
		{
			super();
			ms_loadList = new Dictionary(true);
			ms_loadKeys = new Array();
		}
		
		static public function get instance():JResLoader
		{
			if (_instance == null)
			{
				_instance = new JResLoader(new privateClass());
			}
			return _instance;
			
		}
		
		
		public function set loadSize(value:uint):void
		{
			ms_loadSize = value;
		}
		
		public function get loadSize():uint
		{
			return ms_loadSize;
		}
		
		public function set loadLang(value:uint):void
		{
			ms_loadLang = value;
		}
		
		public function get loadLang():uint
		{
			return ms_loadLang;
		}
		
		/**
		 * 
		 */
		public function setLoadXmlURLResource(url:String):void
		{
			var load:URLLoader = new URLLoader();
			load.addEventListener(Event.COMPLETE,onLoadXmlCompleted,false,0,true);
			load.load(new URLRequest(url));
		}
		
		public function setLoadXmlResource(xml:XML):void
		{
			for each(var node:XML in xml.children())
			{
				this.addLoad(node.@url,node.@id,node.@type,node.@size,node.@lang);
			}
			this.startLoad();
		}
		
		protected function onLoadXmlCompleted(event:Event):void
		{
			var load:URLLoader = event.target as URLLoader;
			if(load)
			{
				var xml:XML = new XML(load.data);
				this.setLoadXmlResource(xml);
				xml = null;
			}
			load = null;
		}
		
		/**添加加载文件
		 * @param url 文件路径
		 * @param id  设置的存储唯一ID
		 * @param type 加载文件类型 0:File 1:Image 2:XML 3:SWF 4:Bin
		 * @param size 当出现相同ID时，跟进size的大小进行选择加载
		 */ 
		protected function addLoad(url:String,id:String,type:uint=JLoaderType.Load_Type_Txt,size:uint=0,lang:uint=0):void
		{
			if(!ms_loadList.hasOwnProperty(id))
			{
				var loadInfo:JLoadInfo = new JLoadInfo();
				loadInfo.url  = url;
				loadInfo.id   = id;
				loadInfo.type = type;
				loadInfo.size = size;
				loadInfo.lang = lang;
				ms_loadKeys.push(id);
				ms_loadList[id] = loadInfo;
			}
			else
			{
				if(ms_loadLang >= lang && ms_loadSize >= size)
				{
					//trace("ms_loadLang=",ms_loadLang,"lang=",lang,"url=",url);
					ms_loadList[id].url = url;
					ms_loadList[id].lang = lang;
					ms_loadList[id].size = size;
				}
			}
		}
		
		public function startLoad():void
		{
			if (ms_loadKeys.length >= 1)
			{
				if(!ms_loadingStatus)
				{
					ms_loadingStatus = true;
					var loadinfo:JLoadInfo = ms_loadList[ms_loadKeys.shift()];
					this._load(loadinfo);
					var evt:JEvent = new JEvent(JEvent.CM_ON_LOAD_PROGRESS);
					this.dispatchEvent(evt);
				}
			}
			else
			{
				var evt:JEvent = new JEvent(JEvent.CM_ON_COMPLETE);
				this.dispatchEvent(evt);
			}
			
		}
		
		public function stopLoad():void
		{
			
		}
		
		protected function _load(loadinfo:JLoadInfo):void
		{
			var load:* = null;
			switch(loadinfo.type)
			{
				case JLoaderType.Load_Type_Txt:
					load = new URLLoader();
					load.addEventListener(Event.COMPLETE,onLoadFileEnd);
					load.addEventListener(IOErrorEvent.IO_ERROR,onLoadError);
					break;
				case JLoaderType.Load_Type_Image:
					load = new Loader();
					load.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadImage);
					load.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onLoadError);
					break;
				case JLoaderType.Load_Type_Xml:
					load = new URLLoader();
					load.addEventListener(Event.COMPLETE,onLoadXmlEnd);
					load.addEventListener(IOErrorEvent.IO_ERROR,onLoadError);
					break;
				case JLoaderType.Load_Type_Swf:
					load = new Loader();
					load.contentLoaderInfo.addEventListener(Event.INIT,onLoadSwfEnd);
					load.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onLoadError);
					break;
				case JLoaderType.Load_Type_BinFile:
					load = new URLLoader();
					load.dataFormat = URLLoaderDataFormat.BINARY;
					load.addEventListener(Event.COMPLETE,onLoadBinFileEnd);
					load.addEventListener(IOErrorEvent.IO_ERROR,onLoadError);
					break;
				default:break;
			}
			if(load)
			{
				ms_curLoadinfo = loadinfo;
				load.load(new URLRequest(loadinfo.url));
			}
		}
		
		protected function onLoadFileEnd(evt:Event):void
		{
			ms_loadingStatus = false;
			var load:URLLoader = evt.target as URLLoader;
			ms_loadList[ms_curLoadinfo.id].data = evt.target.data;
			load.removeEventListener(Event.COMPLETE,onLoadFileEnd);
			this.startLoad();
		}
		
		protected function onLoadXmlEnd(evt:Event):void
		{
			ms_loadingStatus = false;
			var load:URLLoader = evt.target as URLLoader;
			ms_loadList[ms_curLoadinfo.id].data = evt.target.data;
			load.removeEventListener(Event.COMPLETE,onLoadFileEnd);
			this.startLoad();
		}
		
		protected function onLoadBinFileEnd(evt:Event):void
		{
			ms_loadingStatus = false;
			var load:URLLoader = evt.target as URLLoader;
			ms_loadList[ms_curLoadinfo.id].data= load.data as ByteArray;
			load.removeEventListener(Event.COMPLETE, onLoadBinFileEnd);
			if(ms_curLoadinfo.isCallBack)
			{
				ms_curLoadinfo.callFunction(ms_curLoadinfo.id);
			}
			this.startLoad();
		}
		
		protected function onLoadSwfEnd(evt:Event):void
		{
			ms_loadingStatus = false;
			var load:Loader = (evt.currentTarget as LoaderInfo).loader as Loader;
			ms_loadList[ms_curLoadinfo.id].data = load.contentLoaderInfo.applicationDomain;
			load.contentLoaderInfo.removeEventListener(Event.INIT, onLoadSwfEnd);
			if(ms_curLoadinfo.isCallBack)
			{
				ms_curLoadinfo.callFunction(ms_curLoadinfo.id);
			}
			this.startLoad();
		}
		
		protected function onLoadImage(evt:Event):void
		{
			ms_loadingStatus = false;
			var load:Loader = (evt.currentTarget as LoaderInfo).loader as Loader;
			ms_loadList[ms_curLoadinfo.id].data = (load.content as Bitmap).bitmapData;
			load.contentLoaderInfo.removeEventListener(Event.COMPLETE,onLoadImage);
			if(ms_curLoadinfo.isCallBack)
			{
				ms_curLoadinfo.callFunction(ms_curLoadinfo.id);
			}
			this.startLoad();
		}
		protected function onLoadError(evt:IOErrorEvent):void
		{
			var load:LoaderInfo = evt.currentTarget as LoaderInfo;
			trace("加载失败", evt.text);
			ms_loadingStatus = false;
			this.startLoad();
		}
		
		public function onGetClass(id:String,className:String):Class
		{
			if (ms_loadList.hasOwnProperty(id))
			{
				return ms_loadList[id].data.getDefinition(className) as Class;
			}
			return null;
		}
		
		public function onGetBitData(id:String):BitmapData
		{
			if (ms_loadList.hasOwnProperty(id))
			{
				//	trace(id,cacheAList[id])
				return (ms_loadList[id].data as BitmapData).clone();
			}
			return null;
		}
		
		public function onGetFileData(id:String):*
		{
			if(ms_loadList.hasOwnProperty(id))
			{
				return ms_loadList[id].data;
			}
			trace("[waring]:onGetFileData has not id",id)
			return null;
		}
		
		public function onGetXmlData(id:String):XML
		{
			if(ms_loadList.hasOwnProperty(id))
			{
				return new XML(ms_loadList[id].data);
			}
			trace("[waring]:onGetFileData has not id",id)
			return null;
		}
	}
}

class privateClass
{
	
}

